home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 July / EnigmA AMIGA RUN 20 (1997)(G.R. Edizioni)(IT)[!][issue 1997-07 & 08][EAR-CD IV].iso / earcd / text / misc / nroff.lha / nroff / low.c < prev    next >
C/C++ Source or Header  |  1997-02-10  |  14KB  |  1,011 lines

  1. /*
  2.  *    low.c - misc low-level functions for nroff word processor
  3.  *
  4.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  5.  *    net:    rosenkra@hall.cray.com
  6.  *    CIS:    71460,17
  7.  *    GENIE:    W.ROSENKRANZ
  8.  *
  9.  *    original author:
  10.  *
  11.  *    Stephen L. Browning
  12.  *    5723 North Parker Avenue
  13.  *    Indianapolis, Indiana 46220
  14.  *
  15.  *    history:
  16.  *
  17.  *    - Originally written in BDS C;
  18.  *    - Adapted for standard C by W. N. Paul
  19.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  20.  */
  21.  
  22. #undef NRO_MAIN                    /* extern globals */
  23.  
  24. #include <stdio.h>
  25. #include "nroff.h"
  26. #include "ctype.h"
  27.  
  28.  
  29.  
  30. /*------------------------------*/
  31. /*    atod            */
  32. /*------------------------------*/
  33. atod (c)
  34. char    c;
  35. {
  36.  
  37. /*
  38.  *    convert ascii character to decimal.
  39.  */
  40.  
  41.     return (((c < '0') || (c > '9')) ? -1 : c - '0');
  42. }
  43.  
  44.  
  45.  
  46.  
  47.  
  48. /*------------------------------*/
  49. /*    robrk            */
  50. /*------------------------------*/
  51. robrk ()
  52. {
  53.  
  54. /*
  55.  *    end current filled line
  56.  */
  57.  
  58.     if (co.outp > 0)
  59.     {
  60.         /*
  61.          *   handle margin char (change bar) here for all filled lines
  62.          */
  63. #ifndef NOCR
  64.         co.outbuf[co.outp]   = '\r';
  65.         co.outbuf[co.outp+1] = '\n';
  66.         co.outbuf[co.outp+2] = EOS;
  67. #else
  68.         co.outbuf[co.outp] = '\n';
  69.         co.outbuf[co.outp+1] = EOS;
  70. #endif
  71.  
  72.         do_mc (co.outbuf);
  73.  
  74.         put (co.outbuf);
  75.     }
  76.     co.outp   = 0;
  77.     co.outw   = 0;
  78.     co.outwds = 0;
  79.     co.outesc = 0;
  80. }
  81.  
  82.  
  83.  
  84.  
  85. /*------------------------------*/
  86. /*    ctod            */
  87. /*------------------------------*/
  88. ctod (p)
  89. register char  *p;
  90. {
  91.  
  92. /*
  93.  *    convert string to decimal. processes only positive values.
  94.  *    this takes a constant like "1", "1.0i", etc. 
  95.  */
  96.  
  97.     register long    val;
  98.     register int    d;
  99.     register char  *pp = p;
  100.     register char  *ptmp;
  101.     int        rside = 0;
  102.     int        lside = 0;
  103.     int        has_rside = 0;
  104.     int        has_lside = 0;
  105.  
  106.     if (*p == EOS)
  107.         return (0);
  108.  
  109.     ptmp = skipwd (pp);
  110.     pp = --ptmp;
  111.     
  112.     switch (*pp)
  113.     {
  114.     case 'i':
  115.     case 'c':
  116.         val = 0L;
  117.         while (*p != EOS && isdigit (*p))
  118.         {
  119.             has_lside++;
  120.             lside = atod (*p);
  121.             p++;
  122.             if (lside == -1)
  123.                 break;
  124.             val = 10L * val + (long) lside;
  125.         }
  126.         lside = (int) val;
  127.         if (*p == '.')
  128.         {
  129.             p++;
  130.             val = 0L;
  131.             while (*p != EOS && isdigit (*p))
  132.             {
  133.                 has_rside++;
  134.                 rside = atod (*p);
  135.                 p++;
  136.                 if (rside == -1)
  137.                     break;
  138.                 val = 10L * val + (long) rside;
  139.                 if (has_rside > 2)    /* more than enough */
  140.                     break;
  141.             }
  142.             rside = (int) val;
  143.         }
  144.  
  145.         /*
  146.          *   now put it together. 1.0i -> 240, 1.50i -> 360, etc.
  147.          */
  148.         val = 0L;
  149.         if (has_lside)
  150.         {
  151.             val = (long) lside * BU_INCH;
  152.         }
  153.         switch (has_rside)
  154.         {
  155.         case 1:
  156.             val = val + ((long) rside * BU_INCH / 10L);
  157.             break;
  158.         case 2:
  159.             val = val + ((long) rside * BU_INCH / 100L);
  160.             break;
  161.         case 3:
  162.             val = val + ((long) rside * BU_INCH / 1000L);
  163.             break;
  164.         default:
  165.             break;
  166.         }
  167.         if (*pp == 'c')
  168.             val = (val * BU_CM) / BU_INCH;
  169.  
  170.         /*
  171.          *   for now we convert to basic char size, 1 em...
  172.          */
  173.         val = val / BU_EM;
  174.  
  175.         break;
  176.  
  177.     case 'P':
  178.     case 'm':
  179.     case 'n':
  180.     case 'p':
  181.     case 'u':
  182.     case 'v':
  183.         val = 0L;
  184.         while (*p != EOS)
  185.         {
  186.             d = atod (*p);
  187.             p++;
  188.             if (d == -1)
  189.                 break;
  190.             val = 10L * val + (long) d;
  191.         }
  192.         switch (*pp)
  193.         {
  194.         case 'P':
  195.             val = val * BU_PICA;
  196.             break;
  197.         case 'p':
  198.             val = val * BU_POINT;
  199.             break;
  200.         case 'u':
  201.             val = val * BU_BU;
  202.             break;
  203.         case 'm':
  204.             val = val * BU_EM;
  205.             break;
  206.         case 'n':
  207.             val = val * BU_EN;
  208.             break;
  209.         case 'v':
  210.             val = val * BU_EM;
  211.             break;
  212.         }
  213.  
  214.         /*
  215.          *   for now we convert to basic char size, 1 em...
  216.          */
  217.         val = val / BU_EM;
  218.  
  219.         break;
  220.  
  221.     default:
  222.         /*
  223.          *   this is the default behavior. it SHOULD make things
  224.          *   compatible with the old way...
  225.          */
  226.         val = 0L;
  227.         while (*p != EOS)
  228.         {
  229.             d = atod (*p);
  230.             p++;
  231.             if (d == -1)
  232.                 break;
  233.             val = 10L * val + (long) d;
  234.         }
  235.         break;
  236.     }
  237.  
  238.     return ((int) val);
  239. }
  240.  
  241.  
  242.  
  243.  
  244. /*------------------------------*/
  245. /*    inptobu            */
  246. /*------------------------------*/
  247. inptobu (ps)
  248. char   *ps;
  249. {
  250.  
  251. /*
  252.  *    convert input units to b.u.
  253.  */
  254.  
  255.     return;
  256. }
  257.  
  258.  
  259.  
  260.  
  261. /*------------------------------*/
  262. /*    butochar        */
  263. /*------------------------------*/
  264. butochar (ps)
  265. char   *ps;
  266. {
  267.  
  268. /*
  269.  *    convert b.u. to char spaces
  270.  */
  271.  
  272.     return;
  273. }
  274.  
  275.  
  276.  
  277.  
  278. /*------------------------------*/
  279. /*    skipbl            */
  280. /*------------------------------*/
  281. char   *skipbl (p)
  282. register char  *p;
  283. {
  284.  
  285. /*
  286.  *    skip blanks and tabs in character buffer. return ptr to first
  287.  *    non-space or non-tab char. this could mean EOS or \r or \n.
  288.  *    also increments the arg ptr (side effect).
  289.  */
  290.  
  291.     while ((*p != EOS) && (*p == ' ' || *p == '\t'))
  292.         ++p;
  293.     return (p);
  294. }
  295.  
  296.  
  297.  
  298.  
  299. /*------------------------------*/
  300. /*    skipwd            */
  301. /*------------------------------*/
  302. char   *skipwd (p)
  303. register char  *p;
  304. {
  305.  
  306. /*
  307.  *    skip over word and punctuation. anything but space,\t,\r,\n, and EOS
  308.  *    is skipped. return ptr to the first of these found. also increments
  309.  *    the arg ptr (side effect).
  310.  */
  311.  
  312.     while (*p != EOS && *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n')
  313.         ++p;
  314.     return (p);
  315. }
  316.  
  317.  
  318.  
  319.  
  320.  
  321. /*------------------------------*/
  322. /*    space            */
  323. /*------------------------------*/
  324. space (n)
  325. int     n;
  326. {
  327.  
  328. /*
  329.  *    space vertically n lines. this does header and footer also.
  330.  */
  331.  
  332.     robrk ();
  333.     if (pg.lineno > pg.bottom)
  334.         return;
  335.     if (pg.lineno == 0)
  336.         phead ();
  337.     skip (min (n, pg.bottom + 1 - pg.lineno));
  338.     pg.lineno += n;
  339.     set_ireg ("ln", pg.lineno, 0);
  340.     if (pg.lineno > pg.bottom)
  341.         pfoot ();
  342. }
  343.  
  344.  
  345.  
  346.  
  347. /*------------------------------*/
  348. /*    getfield        */
  349. /*------------------------------*/
  350. char   *getfield (p, q, delim)
  351. register char  *p;
  352. register char  *q;
  353. char        delim;
  354. {
  355.  
  356. /*
  357.  *    get field from title
  358.  */
  359.  
  360.     while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS)
  361.     {
  362.         *q++ = *p++;
  363.     }
  364.     *q = EOS;
  365.     if (*p == delim)
  366.         ++p;
  367.     return (p);
  368. }
  369.  
  370.  
  371.  
  372.  
  373.  
  374. /*------------------------------*/
  375. /*    getwrd            */
  376. /*------------------------------*/
  377. getwrd (p0, p1)
  378. register char  *p0;
  379. register char  *p1;
  380. {
  381.  
  382. /*
  383.  *    get non-blank word from p0 into p1.
  384.  *    return number of characters processed.
  385.  */
  386.  
  387.     register int    i;
  388.     register char  *p;
  389.     char        c;
  390.  
  391.     /*
  392.      *   init counter...
  393.      */
  394.     i = 0;
  395.  
  396.  
  397.     /*
  398.      *   skip leading whitespace
  399.      */
  400.     while (*p0 && (*p0 == ' ' || *p0 == '\t'))
  401.     {
  402.         ++i;
  403.         ++p0;
  404.     }
  405.  
  406.  
  407.     /*
  408.      *   set ptr and start to look for end of word
  409.      */
  410.     p = p0;
  411.     while (*p0 != ' ' && *p0 != EOS && *p0 != '\t')
  412.     {
  413.         if (*p0 == '\n' || *p0 == '\r')
  414.             break;
  415.         *p1 = *p0++;
  416.         ++p1;
  417.         ++i;
  418.     }
  419.  
  420.     c = *(p1 - 1);
  421.     if (c == '"')
  422.         c = *(p1 - 2);
  423.     if (c == '?' || c == '!')
  424.     {
  425.         *p1++ = ' ';
  426.         ++i;
  427.     }
  428.     if (c == '.' && (*p0 == '\n' || *p0 == '\r' || islower (*p)))
  429.     {
  430.         *p1++ = ' ';
  431.         ++i;
  432.     }
  433.     *p1 = EOS;
  434.  
  435.     return (i);
  436. }
  437.  
  438.  
  439.  
  440.  
  441. /*------------------------------*/
  442. /*    countesc        */
  443. /*------------------------------*/
  444.  
  445. #define ESC            27
  446.  
  447. countesc (p)
  448. register char  *p;
  449. {
  450.  
  451. /*
  452.  *    count atari escape sequence characters in given null-terminated
  453.  *    string
  454.  */
  455.  
  456.     register char  *pp;
  457.     register int    num;
  458.  
  459.     pp  = p;
  460.     num = 0;
  461.  
  462.     while (*pp != EOS)
  463.     {
  464.         if (*pp == ESC)
  465.         {
  466.             /*
  467.              *   count escape char (atari-specific, vt52)
  468.              *   generally only p,q,b,and c will show up...
  469.              */
  470.             switch (*(pp+1))
  471.             {
  472.             case 'A':            /* ESC-a */
  473.             case 'B':
  474.             case 'C':
  475.             case 'D':
  476.             case 'E':
  477.             case 'H':
  478.             case 'I':
  479.             case 'J':
  480.             case 'K':
  481.             case 'L':
  482.             case 'M':
  483.             case 'd':
  484.             case 'e':
  485.             case 'f':
  486.             case 'j':
  487.             case 'k':
  488.             case 'l':
  489.             case 'o':
  490.             case 'p':
  491.             case 'q':
  492.             case 'v':
  493.             case 'w':
  494.                 num += 2;
  495.                 break;
  496.             case 'b':            /* ESC-a-b */
  497.             case 'c':
  498.                 num += 3;
  499.                 break;
  500.             case 'Y':            /* ESC-a-b-c */
  501.             case '[':            /* Esc [ 7 m */
  502.                 num += 4;
  503.                 break;
  504.             default:
  505.                 num += 1;
  506.                 break;
  507.             }
  508.         }
  509.         pp++;
  510.     }
  511.  
  512.     return (num);
  513. }
  514.  
  515.  
  516.  
  517.  
  518. /*------------------------------*/
  519. /*    itoda            */
  520. /*------------------------------*/
  521. itoda (value, p, size)
  522. int        value;
  523. register char  *p;
  524. register int    size;
  525. {
  526.  
  527. /*
  528.  *    convert integer to decimal ascii string
  529.  */
  530.  
  531.     register int    i;
  532.     register int    j;
  533.     register int    k;
  534.     register int    aval;
  535.     char        c[20];
  536.  
  537.     aval = abs (value);
  538.     c[0] = EOS;
  539.     i = 1;
  540.     do
  541.     {
  542.         c[i++] = (aval % 10) + '0';
  543.         aval /= 10;
  544.  
  545.     } while (aval > 0 && i <= size);
  546.  
  547.     if (value < 0 && i <= size)
  548.         c[i++] = '-';
  549.     for (j = 0; j < i; ++j)
  550.         *p++ = c[i - j - 1];
  551.  
  552.     return (i);
  553. }
  554.  
  555.  
  556.  
  557.  
  558. /*------------------------------*/
  559. /*    itoROMAN        */
  560. /*------------------------------*/
  561. itoROMAN (value, p, size)
  562. int        value;
  563. register char  *p;
  564. register int    size;
  565. {
  566.  
  567. /*
  568.  *    convert integer to upper roman. must be positive
  569.  */
  570.  
  571.     register int    i;
  572.     register int    j;
  573.     register int    k;
  574.     register int    aval;
  575.     char        c[100];
  576.     int        rem;
  577.  
  578.     aval = abs (value);
  579.     c[0] = EOS;
  580.     i = 1;
  581.  
  582.     /*
  583.      *   trivial case:
  584.      */
  585.     if (aval == 0)
  586.     {
  587.         c[i++] = '0';
  588.         goto done_100;
  589.     }
  590.  
  591.     /*
  592.      *   temporarily mod 100...
  593.      */
  594.     aval = aval % 100;
  595.  
  596.     if (aval > 0)
  597.     {
  598.         /*
  599.          *   build backward
  600.          *
  601.          *   | I|        1
  602.          *   | II|        2
  603.          *   | III|        3
  604.          *   | VI|        4
  605.          *   | V|        5
  606.          *   | IV|        6
  607.          *   | IIV|        7
  608.          *   | IIIV|        8
  609.          *   | XI|        9
  610.          *   | X|        0
  611.          *   | IX|        11
  612.          *   | IIX|        12
  613.          */
  614.         if ((aval % 5 == 0) && (aval % 10 != 0))/* 5 */
  615.             c[i++] = 'V';
  616.         else
  617.         {
  618.             rem = aval % 10;
  619.             if (rem == 9)            /* 9 */
  620.             {
  621.                 c[i++] = 'X';
  622.                 c[i++] = 'I';
  623.             }
  624.             else if (rem == 8)        /* 8 */
  625.             {
  626.                 c[i++] = 'I';
  627.                 c[i++] = 'I';
  628.                 c[i++] = 'I';
  629.                 c[i++] = 'V';
  630.             }
  631.             else if (rem == 7)        /* 7 */
  632.             {
  633.                 c[i++] = 'I';
  634.                 c[i++] = 'I';
  635.                 c[i++] = 'V';
  636.             }
  637.             else if (rem == 6)        /* 6 */
  638.             {
  639.                 c[i++] = 'I';
  640.                 c[i++] = 'V';
  641.             }
  642.             else if (rem == 4)        /* 4 */
  643.             {
  644.                 c[i++] = 'V';
  645.                 c[i++] = 'I';
  646.             }
  647.             else                /* 3,2,1 */
  648.             {
  649.                 for (j = 0; j < rem; j++)
  650.                     c[i++] = 'I';
  651.             }
  652.         }
  653.  
  654.         aval /= 10;
  655.         if (aval == 0)
  656.             goto done_100;
  657.  
  658.         rem = aval % 10;
  659.         if (rem == 4)
  660.         {
  661.             c[i++] = 'L';
  662.             c[i++] = 'X';
  663.         }
  664.         else if (rem == 5)
  665.         {
  666.             c[i++] = 'L';
  667.         }
  668.         else if (rem < 4)
  669.         {
  670.             for (j = 0; j < rem; j++)
  671.                 c[i++] = 'X';
  672.         }
  673.         else
  674.         {
  675.             for (j = 0; j < rem - 5; j++)
  676.                 c[i++] = 'X';
  677.             c[i++] = 'L';
  678.         }
  679.     }
  680.  
  681.  
  682. done_100:
  683.     /*
  684.      *   divide by 100 (they are done) and temp mod by another 10
  685.      */
  686.     aval  = abs (value);
  687.     aval /= 100;
  688.  
  689.     if (aval > 0)
  690.     {
  691.         rem  = aval % 10;
  692.         if (rem == 4)
  693.         {
  694.             c[i++] = 'D';
  695.             c[i++] = 'C';
  696.         }
  697.         if (rem == 5)
  698.         {
  699.             c[i++] = 'D';
  700.         }
  701.         else if (rem < 4)
  702.         {
  703.             for (j = 0; j < rem; j++)
  704.                 c[i++] = 'C';
  705.         }
  706.         else if (rem == 9)
  707.         {
  708.             c[i++] = 'M';
  709.             c[i++] = 'C';
  710.         }
  711.         else if (rem < 9)
  712.         {
  713.             for (j = 0; j < rem - 5; j++)
  714.                 c[i++] = 'C';
  715.             c[i++] = 'D';
  716.         }
  717.     }
  718.  
  719.  
  720.     aval /= 10;
  721.  
  722.     if (aval > 0)
  723.     {
  724.         rem  = aval % 10;
  725.         if (rem < 4)
  726.         {
  727.             for (j = 0; j < rem; j++)
  728.                 c[i++] = 'M';
  729.         }
  730.     }
  731.  
  732.  
  733.     if (value < 0)
  734.         c[i++] = '-';
  735.  
  736.     for (j = 0; j < i; ++j)
  737.         *p++ = c[i - j - 1];
  738.  
  739.     return (i);
  740. }
  741.  
  742.  
  743.  
  744.  
  745. /*------------------------------*/
  746. /*    itoroman        */
  747. /*------------------------------*/
  748. itoroman (value, p, size)
  749. int     value;
  750. char   *p;
  751. int     size;
  752. {
  753.  
  754. /*
  755.  *    convert integer to lower roman
  756.  */
  757.  
  758.     register int    i;
  759.     register int    len;
  760.     register int    aval;
  761.     char        c[100];
  762.  
  763.     c[0] = EOS;
  764.     len = itoROMAN (value, c, size);
  765.  
  766.     for (i = 0; i < len; i++)
  767.     {
  768.         p[i] = c[i];
  769.         if (isalpha (p[i]))
  770.             p[i] = tolower (c[i]);
  771.     }
  772.  
  773.     return (len);
  774. }
  775.  
  776.  
  777.  
  778.  
  779. /*------------------------------*/
  780. /*    itoLETTER        */
  781. /*------------------------------*/
  782. itoLETTER (value, p, size)
  783. int        value;
  784. register char  *p;
  785. register int    size;
  786. {
  787.  
  788. /*
  789.  *    convert integer to upper letter value: 0,A,B,C,...,AA,AB,AC,...
  790.  */
  791.  
  792.     register int    i;
  793.     register int    j;
  794.     register int    k;
  795.     register int    aval;
  796.     int        rem;
  797.     char        c[20];
  798.  
  799.     aval = abs (value);
  800.     c[0] = EOS;
  801.     i = 1;
  802.  
  803.     /*
  804.      *   1 based:
  805.      *
  806.      *   0    0
  807.      *   1    A
  808.      *   25    Z
  809.      *   26    AA
  810.      *   51 AZ
  811.      *   52 AAA
  812.      *   ...
  813.      */
  814.     if (aval == 0)
  815.         c[i++] = '0';
  816.     else if (aval < 27)
  817.     {
  818.         c[i++] = aval - 1 + 'A';
  819.     }
  820.     else
  821.     {
  822.         do
  823.         {
  824.             c[i++] = ((aval - 1) % 26) + 'A';
  825.             aval = (aval - 1)  / 26;
  826.     
  827.         } while (aval > 0 && i <= size);
  828.     }
  829.  
  830.     if (value < 0 && i <= size)
  831.         c[i++] = '-';
  832.  
  833.     for (j = 0; j < i; ++j)
  834.         *p++ = c[i - j - 1];
  835.  
  836.     return (i);
  837. }
  838.  
  839.  
  840.  
  841. /*------------------------------*/
  842. /*    itoletter        */
  843. /*------------------------------*/
  844. itoletter (value, p, size)
  845. int        value;
  846. register char  *p;
  847. register int    size;
  848. {
  849.  
  850. /*
  851.  *    convert integer to upper letter value: 0,a,b,c,...,aa,ab,ac,...
  852.  */
  853.  
  854.     register int    i;
  855.     register int    j;
  856.     register int    k;
  857.     register int    aval;
  858.     char        c[20];
  859.     int        rem;
  860.  
  861.     aval = abs (value);
  862.     c[0] = EOS;
  863.     i = 1;
  864.  
  865.     /*
  866.      *   1 based:
  867.      *
  868.      *   0    0
  869.      *   1    A
  870.      *   25    Z
  871.      *   26    AA
  872.      *   51 AZ
  873.      *   52 AAA
  874.      *   ...
  875.      */
  876.     if (aval == 0)
  877.         c[i++] = '0';
  878.     else if (aval < 27)
  879.     {
  880.         c[i++] = aval - 1 + 'a';
  881.     }
  882.     else
  883.     {
  884.         do
  885.         {
  886.             c[i++] = ((aval - 1) % 26) + 'a';
  887.             aval = (aval - 1)  / 26;
  888.     
  889.         } while (aval > 0 && i <= size);
  890.     }
  891.  
  892.     if (value < 0 && i <= size)
  893.         c[i++] = '-';
  894.  
  895.     for (j = 0; j < i; ++j)
  896.         *p++ = c[i - j - 1];
  897.  
  898.     return (i);
  899. }
  900.  
  901.  
  902.  
  903. /*------------------------------*/
  904. /*    min            */
  905. /*------------------------------*/
  906.  
  907. #ifdef min
  908. #undef min
  909. #endif
  910.  
  911. min (v1, v2)
  912. register int    v1;
  913. register int    v2;
  914. {
  915.  
  916. /*
  917.  *    find minimum of two integer ONLY
  918.  */
  919.  
  920.     return ((v1 < v2) ? v1 : v2);
  921. }
  922.  
  923.  
  924.  
  925.  
  926.  
  927. /*------------------------------*/
  928. /*    max            */
  929. /*------------------------------*/
  930.  
  931. #ifdef max
  932. #undef max
  933. #endif
  934.  
  935. max (v1, v2)
  936. register int    v1;
  937. register int    v2;
  938. {
  939.  
  940. /*
  941.  *    find maximum of two integers ONLY
  942.  */
  943.  
  944.     return ((v1 > v2) ? v1 : v2);
  945. }
  946.  
  947.  
  948.  
  949.  
  950.  
  951. /*------------------------------*/
  952. /*    err_exit        */
  953. /*------------------------------*/
  954. err_exit (code)
  955. {
  956.  
  957. /*
  958.  *    exit cleanly on fatal error (close files, etc). also handles normal
  959.  *    exit.
  960.  */
  961.  
  962.     if (err_stream != stderr && err_stream != (FILE *) 0)
  963.     {
  964.         /*
  965.          *   not going to stderr (-o file)
  966.          */
  967.         fflush (err_stream);
  968.         fclose (err_stream);
  969.     }
  970.     if (debugging && dbg_stream != stderr && dbg_stream != (FILE *) 0)
  971.     {
  972.         fflush (dbg_stream);
  973.         fclose (dbg_stream);
  974.     }
  975.     if (out_stream != stdout && out_stream != (FILE *) 0)
  976.     {
  977.         /*
  978.          *   not going to stdout (-l)
  979.          */
  980.         fflush (out_stream);
  981.         fclose (out_stream);
  982.     }
  983.  
  984.     if (hold_screen)
  985.     {
  986.         wait_for_char ();
  987.     }
  988.  
  989.     exit (code);
  990. }
  991.  
  992.  
  993.  
  994. /*------------------------------*/
  995. /*    wait_for_char        */
  996. /*------------------------------*/
  997. #ifdef GEMDOS
  998. #include <osbind.h>
  999. #endif
  1000.  
  1001. wait_for_char ()
  1002. {
  1003. #ifdef GEMDOS
  1004.         printf ("enter any key..."); fflush (stdout);
  1005.         Cconin ();
  1006. #endif
  1007. }
  1008.  
  1009.  
  1010.  
  1011.